<template>
  <div class="department-container">
    <div class="app-container">
      <el-card>
        <!-- 用一个行列布局 -->
        <el-row type="flex" justify="space-between" align="middle" style="height: 40px">
          <el-col :span="20">
            <span>江苏传智播客教育科技股份有限公司</span>
          </el-col>
          <el-col :span="4">
            <el-row type="flex" justify="end">
              <!-- 两个内容 -->
              <el-col>负责人</el-col>
              <el-col>操作</el-col>
            </el-row>
          </el-col>
        </el-row>
        <!-- 树形组件 -->
        <el-tree
          :data="list"
          :props="defaultProps"
          :default-expand-all="true"
        >
          <!-- 作用域插槽 data拿到的是每一个子节点的对象 -->
          <template #default="{ data }">
            <!-- 自定义模板 -->
            <el-row
              type="flex"
              justify="space-between"
              align="middle"
              style="height: 40px; width: 100%;"
            >
              <el-col :span="20">
                <span>{{ data.name }}</span>
              </el-col>
              <el-col :span="4">
                <el-row type="flex" justify="end">
                  <!-- 两个内容 -->
                  <el-col>{{ data.manager }}</el-col>
                  <el-col>
                    <!-- 下拉菜单 element -->
                    <el-dropdown>
                      <span> 操作<i class="el-icon-arrow-down" /> </span>
                      <el-dropdown-menu slot="dropdown">
                        <el-dropdown-item @click.native="addVisible(data.id)">添加子部门</el-dropdown-item>
                        <el-dropdown-item @click.native="editDepart(data.id)">编辑部门</el-dropdown-item>
                        <el-dropdown-item @click.native="delDepart(data.id)">删除部门</el-dropdown-item>
                      </el-dropdown-menu>
                    </el-dropdown>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-tree>
      </el-card>
    </div>
    <!-- 新增部门的弹层 -->
    <el-dialog title="新增部门" :visible="dialogVisible" @close="closeAddDialog" @open="openAddDialog">
      <el-form ref="AddForm" :model="form" :rules="rules" label-width="120px">
        <el-form-item label="部门名称" prop="name">
          <el-input v-model="form.name" style="width:80%" placeholder="1-50个字符" />
        </el-form-item>
        <el-form-item label="部门编码" prop="code">
          <el-input v-model="form.code" style="width:80%" placeholder="1-50个字符" />
        </el-form-item>
        <el-form-item label="部门负责人" prop="manager">
          <el-select v-model="form.manager" style="width:80%" placeholder="请选择">
            <el-option
              v-for="item in managerList"
              :key="item.id"
              :value="item.username"
              :label="item.username"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="部门介绍" prop="introduce">
          <el-input v-model="form.introduce" style="width:80%" placeholder="1-300个字符" type="textarea" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button type="primary" size="small" @click="confirm">确定</el-button>
        <el-button size="small">取消</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
/**
 * 1.获取列表渲染
 * 思路：1.定义一个响应式数据-》2.调用接口获取数据 -》3.把数据赋值给响应式的属性
 * created mounted 在当前的场景下  写道这两个里面毫无差别
 * mounted优势：dom可用 echarts图标渲染  百度地图渲染
 * 服务端渲染：没有mounted钩子函数 不可用
 * 拓展问题二：为什么要单独封装一个getList
 * 1.结构清晰  生命周期钩子函数都不应该包含太多的逻辑代码 初始化的调用代码
 * 2.方便复用  在这个函数里面封装好更新列表的所有逻辑{参数二次处理  数据获取到赋值  二次处理}
 *
 */
/**
 * 新增实现
 *
 */
import { fetchDepartmentList, fetchManagerList, fetchAddDepart, delDepartments, getDepartDetail, fetchUpdateDepart } from '@/api/department'
import transTree from '@/utils/transTree'
export default {
  name: 'Department',
  data() {
    // code不可以和已经存在的code出现重复
    const validatePass = (rule, value, callback) => {
      // 1. 声明一个空的codeList
      // 2. 判断当前是编辑还是新增 如果是新增 codelist就存放所有的code码
      // 如果是编辑状态 先把当前项已经回填的code从所有的codelist中删除 创建一个新的复制一份 删除这一份
      // 不要删除form里的 code 因为双向绑定 再赋值给codeList
      // 3. 开始使用数组的includes方法进行判断

      // 编辑的时候：自己和自己重复了  这时候容许
      // 解决方法：如果是在编辑的状态下需要在codeList中把自己的code过滤掉filter
      // 如果是新增状态 codeList  就是所有的  入关当枪使便将状态codeList就是去掉cachCode之后的
      let codeList = []
      if (!this.form.id) {
        // 去掉cacheCode
        codeList = this.codelist
      } else {
        codeList = this.codelist.filter(code => code !== this.cacheCode)
      }
      if (codeList.includes(value)) {
        // 重复
        callback(new Error('重复啦，请换一个'))
      } else {
        callback()
      }
    }
    return {
      // 依赖一份树形数据
      list: [{
        name: '财务部',
        manager: 'zhangsan',
        children: [
          {
            name: '财务核算部',
            manager: 'lisi'
          },
          {
            name: '税务核算部',
            manager: 'wangwu'
          }
        ]
      }],
      form: {
        name: '',
        code: '',
        introduce: '',
        manager: '',
        pid: '', // 当前要给谁新增子部门  代表它的id
        curId: ''
      },
      codelist: [],
      managerList: [],
      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门名称要求1-50个字符', trigger: ['blur', 'change'] }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门编码要求1-50个字符', trigger: ['blur', 'change'] },
          { required: true, validator: validatePass, trigger: 'blur' }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: ['blur', 'change'] }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 300, message: '部门介绍要求1-300个字符', trigger: ['blur', 'change'] }
        ]
      },
      defaultProps: {
        label: 'name'
      },
      dialogVisible: false,
      cacheCode: null
    }
  },
  mounted() {
    this.getList()
  },
  methods: {
    async getList() {
      const res = await fetchDepartmentList()
      // 目标：把后端返回的平铺的数组转化成组件需要的树形数组
      // 解决问题：1.直接搜方案2.自己写
      // console.log(res.deptgis)
      this.list = transTree(res.depts)
      // console.log(res.depts)
      res.depts.forEach(item => {
        this.codelist.push(item.code)
      })
    },
    addVisible(id) {
      this.form.pid = id
      this.dialogVisible = true
    },

    // 打开弹框
    async openAddDialog() {
      const res = await fetchManagerList()
      this.managerList = res
    },
    // 关闭弹框
    closeAddDialog() {
      this.dialogVisible = false
      this.$refs.AddForm.resetFields()
    },
    // 兜底校验
    confirm() {
      this.$refs.AddForm.validate(async(valid) => {
        if (valid) {
          // 是否有id 有id为修改  没有id为新增

          if (this.form.id) {
            // 获取表单信息
            await fetchUpdateDepart(this.form)
          } else {
            await fetchAddDepart(this.form)
          }
          // 提示信息
          this.$message.success('新增部门成功')
          // 关闭表单
          this.dialogVisible = false
          // 重新渲染表单
          this.getList()
          // 重置清空表单
          this.$refs.AddForm.resetFields()
          this.compileForm()
        }
      })
    },
    compileForm() {
      this.form = {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '', // 部门介绍
        pid: ''
      }
    },
    // 删除
    delDepart(id) {
      this.$confirm('你确认要进行删除么?', '温馨提示').then(async() => {
        // 删除操作成功
        await delDepartments(id)
        // 删除成功后续操作
        this.$message.success('删除操作成功')
        // 重新渲染页面
        this.getList()
      })
    },
    // 编辑
    async editDepart(id) {
      // 表单显示
      this.dialogVisible = true
      // 获取详情
      const res = await getDepartDetail(id)
      // 放入表单中
      this.form = res
      // 把code赋值给自定义的
      this.cacheCode = res.code
    }

  }
}
</script>

<style>
</style>
